package com.ljx.config;

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

/**
 * Company: 上海数惠系统技术有限公司
 * Department: 数据中心：研发二部
 * Date: 2021/04/11 17:17
 *
 * @Author: Ljxpa
 * Email: lujx@dist.com.cn
 * Desc:
 */
@Configuration
@EnableJpaRepositories(value = "com.ljx.dao", //指定jpa接口所在
		entityManagerFactoryRef = "determineEntityManagerFactory",//指定entityManagerFactory
		transactionManagerRef = "determineTransactionManager")//指定事务管理器
public class SwitchDatasourceConfig {

	@Bean("readDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.hikari.read")
	public DataSource d1(){
		HikariDataSource build = DataSourceBuilder.create().type(HikariDataSource.class).build();
		return build;
	}

	@Primary //必须设置一个主数据源，用于spring装载EntityManagerFactoryBuilder等其它bean
	@Bean("writeDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.hikari.write")
	public DataSource d2(){
		HikariDataSource build = DataSourceBuilder.create().type(HikariDataSource.class).build();
		return build;
	}


	@Autowired
	JpaProperties jpaProperties;

	/**
	 * 我们通过LocalContainerEntityManagerFactoryBean来获取EntityManagerFactory实例
	 *
	 * @return
	 */
	@Bean(name = "determineEntityManagerFactoryBean")
	public LocalContainerEntityManagerFactoryBean writeEntityManagerFactoryBean(
			EntityManagerFactoryBuilder builder,
			@Qualifier("routingDataSource") DataSource dataSource) {
		return builder
				.dataSource(dataSource)
				.properties(jpaProperties.getProperties())
				.packages("com.ljx.model.entity") // 设置实体类所在位置
				.persistenceUnit("determinePersistenceUnit")
				.build();
	}

	/**
	 * EntityManagerFactory类似于Hibernate的SessionFactory，mybatis的SqlSessionFactory
	 * 总之在执行操作之前我们总要获取一个EntityManager，这就类似于Hibernate的Session，mybatis的sqlSession。
	 *
	 * @return
	 */
	@Bean(name = "determineEntityManagerFactory")
	@Primary
	public EntityManagerFactory writeEntityManagerFactory(
			@Qualifier("determineEntityManagerFactoryBean") LocalContainerEntityManagerFactoryBean factoryBean) {
		return factoryBean.getObject();
	}

	/**
	 * 配置事物管理器
	 *
	 * @return
	 */
	@Bean(name = "determineTransactionManager")
	@Primary
	public PlatformTransactionManager writeTransactionManager(
			@Qualifier("determineEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
		return new JpaTransactionManager(entityManagerFactory);
	}
}
